/* GPS DS-GPM.S */

#include "Defines.h"
#include "GPS.h"

/* Fonction d'acquisition d'un octet */
int acquire()
{
  int val = 0;
  
  // Initialisation de la communication
  Wire.beginTransmission(GPSADDRESS);
  Wire.send(registre);
  Wire.endTransmission();
  
  // Demande d'acquisition d'un octet
  Wire.requestFrom(GPSADDRESS, 1);
  while(Wire.available() < 1);	// attente d'un byte disponible		      
  val = Wire.receive();  // reception du byte
  
  return val;
 
}
  

/* Affichage du mode du GPS */
char getMode()
{
  /* A = Autonomous Mode, D = Differential Mode, E = Estimated Mode (Dead Reckoning), M = Manual input Mode, S = Simulated Mode, N = Data Not Valid */
  char mode;
  
  registre = 56;
  
  mode = acquire();
  
  Serial.println(mode, BYTE);
  Serial.println(" ");
  
  return mode;
}
  
/* Affichage de l'heure */
void displayTime()
{
  byte hourTen, hourUn, minuteTen, minuteUn, secondTen, secondUn;
  
  // On initialise la lecture au niveau du registre 0
  Wire.beginTransmission(GPSADDRESS);
  Wire.send(0);
  Wire.endTransmission();
  
  // Demande de reception de la part du maitre
  Wire.requestFrom(GPSADDRESS, 6);
  
  // Lecture des registres
  hourTen = Wire.receive();
  hourUn = Wire.receive();
  minuteTen = Wire.receive();
  minuteUn = Wire.receive();
  secondTen = Wire.receive();
  secondUn = Wire.receive();
  
  // Affichage de l'heure
  Serial.print(hourTen, DEC);
  Serial.print(hourUn, DEC);
  Serial.print(":");
  Serial.print(minuteTen, DEC);
  Serial.print(minuteUn, DEC);
  Serial.print(":");
  Serial.print(secondTen, DEC);
  Serial.print(secondUn, DEC);
  Serial.println(" UTC");
  
}

/*Affichage de la lattitude */
void displayLatitude()
{
  byte latDegTen, latDegUn, latMinTen, latMinUn, latMinTenths, latMinHundredths, latMinThousandths, latMinTenThousandths, latDir;
  
  // On initialise la lecture au niveau du registre 14
  Wire.beginTransmission(GPSADDRESS);
  Wire.send(14);
  Wire.endTransmission();
  
  // Demande de reception de la part du maitre
  Wire.requestFrom(GPSADDRESS, 9);
  
  // Reception
  latDegTen = Wire.receive();
  latDegUn = Wire.receive();
  latMinTen = Wire.receive();
  latMinUn = Wire.receive();
  latMinTenths = Wire.receive();
  latMinHundredths = Wire.receive();
  latMinThousandths = Wire.receive();
  latMinTenThousandths = Wire.receive();
  latDir = Wire.receive();
  
  // Affichage de la lattitude
  Serial.print(latDegTen, DEC);
  Serial.print(latDegUn, DEC);
  Serial.print(" degrees ");
  Serial.print(latMinTen, DEC);
  Serial.print(latMinUn, DEC);
  Serial.print(",");
  Serial.print(latMinTenths, DEC);
  Serial.print(latMinHundredths, DEC);
  Serial.print(latMinThousandths, DEC);
  Serial.print(latMinTenThousandths, DEC);
  Serial.print(" minutes ");
  Serial.println(latDir);
  
}

/* Fonction renvoyant la latitude en radians */
float getLatitude()
{
  float latitude;
  float minutes;
  byte letter;
  
  registre = 14;
  
  data = acquire();
  latitude = data*10;
  registre++;
  
  data = acquire();
  latitude = latitude + data;
  registre++;
  
  data = acquire();
  minutes = data*10;
  registre++;
  
  data = acquire();
  minutes = minutes + data;
  registre++;
  
  data = acquire();
  minutes = minutes + data/10;
  registre++;
  
  data = acquire();
  minutes = minutes + data/100;
  registre++;
  
  data = acquire();
  minutes = minutes + data/1000;
  registre++;
  
  data = acquire();
  minutes = minutes + data/10000;
  latitude = latitude + (minutes/60);
  registre++;
  
  data = acquire();
  letter = data;
  if (letter == 'S')
    latitude = -latitude;
  
  return radians(latitude);
  
}

/*Affichage de la longitude */
void displayLongitude()
{
  byte longDegHundred, longDegTen, longDegUn, longMinTen, longMinUn, longMinTenths, longMinHundredths, longMinThousandths, longMinTenThousandths, longDir;
  
  // On initialise la lecture au niveau du registre 23
  Wire.beginTransmission(GPSADDRESS);
  Wire.send(23);
  Wire.endTransmission();
  
  // Demande de reception de la part du maitre
  Wire.requestFrom(GPSADDRESS, 10);
  
  // Reception
  longDegHundred = Wire.receive();
  longDegTen = Wire.receive();
  longDegUn = Wire.receive();
  longMinTen = Wire.receive();
  longMinUn = Wire.receive();
  longMinTenths = Wire.receive();
  longMinHundredths = Wire.receive();
  longMinThousandths = Wire.receive();
  longMinTenThousandths = Wire.receive();
  longDir = Wire.receive();
  
  // Affichage de la lattitude
  Serial.print(longDegHundred, DEC);
  Serial.print(longDegTen, DEC);
  Serial.print(longDegUn, DEC);
  Serial.print(" degrees ");
  Serial.print(longMinTen, DEC);
  Serial.print(longMinUn, DEC);
  Serial.print(",");
  Serial.print(longMinTenths, DEC);
  Serial.print(longMinHundredths, DEC);
  Serial.print(longMinThousandths, DEC);
  Serial.print(longMinTenThousandths, DEC);
  Serial.print(" minutes ");
  Serial.println(longDir);
  
}

/* Fonction renvoyant la longitude en radians */
float getLongitude()
{
  float longitude;
  float minutes;
  byte letter;
  
  registre = 23;
  
  data = acquire();
  longitude = data*100;
  registre++;
  
  data = acquire();
  longitude += data*10;
  registre++;
  
  data = acquire();
  longitude += data;
  registre++;
  
  data = acquire();
  minutes = data*10;
  registre++;
  
  data = acquire();
  minutes += data;
  registre++;
  
  data = acquire();
  minutes += data/10;
  registre++;
  
  data = acquire();
  minutes += data/100;
  registre++;
  
  data = acquire();
  minutes += data/1000;
  registre++;
  
  data = acquire();
  minutes += data/10000;
  longitude = longitude + (minutes/60);
  registre++;
  
  data = acquire();
  letter = data;
  if (letter == 'W')
    longitude = -longitude;
  
  return radians(longitude);
  
}
  
/* Affichage du cap par rapport au Nord vrai */
void displayHeading()
{
  byte headingDegHun, headingDegTen, headingDegUn, headingDegTenths;
  
  // On initialise la lecture au niveau du registre 44
  Wire.beginTransmission(GPSADDRESS);
  Wire.send(44);
  Wire.endTransmission();
  
  // Demande de reception de la part du maitre
  Wire.requestFrom(GPSADDRESS, 4);
  
  // Lecture des registres
  headingDegHun = Wire.receive();
  headingDegTen = Wire.receive();
  headingDegUn = Wire.receive();
  headingDegTenths = Wire.receive();
  
  // Affichage du cap
  Serial.print("Heading : ");
  Serial.print(headingDegHun, DEC);
  Serial.print(headingDegTen, DEC);
  Serial.print(headingDegUn, DEC);
  Serial.print(",");
  Serial.println(headingDegTenths, DEC);
 
}

/* Fonction renvoyant le cap */
float getHeading()
{
  float heading;
  
  registre = 44;
  
  data = acquire();
  heading = data*100;
  registre++;
  
  data = acquire();
  heading += data*10;
  registre++;
  
  data = acquire();
  heading += data;
  registre++;
  
  data = acquire();
  heading += (data)/10;
  
  heading = radians(heading);
  
  return heading;
 
}
  

/* Affichage de la vitesse */
void displaySpeed()
{
  byte speedHun, speedTen, speedUn, speedTenths;
  
  // On initialise la lecture au niveau du registre 52
  Wire.beginTransmission(GPSADDRESS);
  Wire.send(52);
  Wire.endTransmission();
  
  // Demande de reception de la part du maitre
  Wire.requestFrom(GPSADDRESS, 4);
  
  // Lecture des registres
  speedHun = Wire.receive();
  speedTen = Wire.receive();
  speedUn = Wire.receive();
  speedTenths = Wire.receive();
  
  // Affichage de la vitesse
  Serial.print("Speed : ");
  Serial.print(speedHun, DEC);
  Serial.print(speedTen, DEC);
  Serial.print(speedUn, DEC);
  Serial.print(",");
  Serial.print(speedTenths, DEC);
  Serial.println(" km/h");
 
}

/* Fonction renvoyant la vitesse */
float getSpeed()
{
  float vitesse;
  registre = 52;
  
  data = acquire();
  vitesse = data*100;
  registre++;
  
  data = acquire();
  vitesse += data*10;
  registre++;
  
  data = acquire();
  vitesse += data;
  registre++;
  
  data = acquire();
  vitesse += data/10;
  
  return vitesse;
  
}

/* Affichage de l'altitude */
void displayAltitude()
{
  byte altTenThousands, altThousands, altHun, altTen, altUn;
  
  // On initialise la lecture au niveau du registre 39
  Wire.beginTransmission(GPSADDRESS);
  Wire.send(39);
  Wire.endTransmission();
  
  // Demande de reception de la part du maitre
  Wire.requestFrom(GPSADDRESS, 5);
  
  // Lecture des registres
  altTenThousands = Wire.receive();
  altThousands = Wire.receive();
  altHun = Wire.receive();
  altTen = Wire.receive();
  altUn = Wire.receive();
  
  // Affichage de l'altitude
  Serial.print("Altitude : ");
  Serial.print(altTenThousands, DEC);
  Serial.print(altThousands, DEC);
  Serial.print(altHun, DEC);
  Serial.print(altTen, DEC);
  Serial.print(altUn, DEC);
  Serial.println(" metres");
 
}
